# -*- coding: utf-8 -*-
from typing import Sequence

from sqlalchemy import Select
from fastapi import Request

from App.app.admin.crud.menu_crud import MenuDao
from App.app.admin.crud.sys_role_crud import SysRoleDao
from App.app.admin.models.sys_role import SysRole
from App.app.admin.schemas.sys_role_schema import CreateSysRoleParam, UpdateSysRoleParam, UpdateRoleMenuParam
from App.common.exception import errors
from App.common.exception.errors import CustomError
from App.config.conf import settings
from App.database.mysql import async_db_session
from App.database.redis import redis_client


class SysRoleServices:
    @staticmethod
    async def get(*, pk: int) -> SysRole:
        async with async_db_session() as db:
            sys_role = await SysRoleDao.get(db, pk)
            if not sys_role:
                raise errors.NotFoundError(message='数据不存在')
            return sys_role

    @staticmethod
    async def get_select(name: str = None, status: str = None) -> Select:
        return await SysRoleDao.get_list(name=name, status=status)

    @staticmethod
    async def get_all() -> Sequence[SysRole]:
        async with async_db_session() as db:
            sys_roles = await SysRoleDao.get_all(db)
            return sys_roles

    @staticmethod
    async def create(*, obj_in: CreateSysRoleParam) -> SysRole:
        async with async_db_session.begin() as db:
            role = await SysRoleDao.get_by_name(db, obj_in.name)
            if role:
                raise CustomError(message='角色已存在')
            return await SysRoleDao.create(db, obj_in)

    @staticmethod
    async def update(*, obj_in: UpdateSysRoleParam) -> int:
        async with async_db_session.begin() as db:
            pk = obj_in.id
            count = await SysRoleDao.update(db, pk, obj_in)
            return count

    @staticmethod
    async def delete(*, pk: int) -> int:
        async with async_db_session.begin() as db:
            count = await SysRoleDao.delete(db, pk)
            return count

    @staticmethod
    async def update_role_menu(*, request: Request, obj_in: UpdateRoleMenuParam) -> int:
        async with async_db_session.begin() as db:
            role = await SysRoleDao.get(db, obj_in.id)
            if not role:
                raise CustomError(message='角色不存在')
            for menu_id in obj_in.menus:
                menu = await MenuDao.get(db, menu_id)
                if not menu:
                    raise CustomError(message='菜单不存在')
            count = await SysRoleDao.update_menus(db, obj_in)
            if obj_in.id == request.user.role_id:
                await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
            return count


SysRoleService: SysRoleServices = SysRoleServices()
